package cn.tedu.charging.order.mqtt;

import cn.tedu.charging.common.constant.Constants;
import cn.tedu.charging.common.constant.MqttConstants;
import cn.tedu.charging.common.constant.OrderStatusConstants;
import cn.tedu.charging.common.pojo.param.ChargingProgressParam;
import cn.tedu.charging.common.pojo.vo.ChargingProgressVO;
import cn.tedu.charging.common.pojo.vo.JsonResult;
import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.order.pojo.dto.ChargingProgressDTO;
import cn.tedu.charging.order.pojo.dto.ChargingResultDTO;
import cn.tedu.charging.order.pojo.po.ChargingFailPO;
import cn.tedu.charging.order.pojo.po.ChargingSuccessPO;
import com.alibaba.nacos.api.utils.StringUtils;
import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * EMQX的消息中间的 消费者
 * 订单服务 用来 接收 设备发送的消息
 */
@Slf4j
public class MqttConsumer implements MqttCallbackExtended {
    private MqttClient mqttClient;
    private MqttContext mqttContext;

    public MqttConsumer(MqttClient mqttClient, MqttContext mqttContext) {
        this.mqttClient = mqttClient;
        this.mqttContext = mqttContext;
    }

    @Override
    public void connectComplete(boolean retry, String url) {
        log.debug("MqttConsumer#connectComplete方法被调用了，表示连接成功," + "retry:{},url:{}", retry, url);
        try {
            log.debug("连接成功，开始订阅消息,url:{}", url);
            mqttClient.subscribe(MqttConstants.TOPIC_CHARGING_RESULT);
            mqttClient.subscribe(MqttConstants.TOPIC_CHARGING_PROGRESS);
            log.debug("连接成功，成功订阅信息,url:{}", url);
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void connectionLost(Throwable throwable) {
        log.debug("MqttConsumer#connectionLost方法被调用了，表示消息丢失");
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        log.debug("MqttConsumer#messageArrived方法被调用了，表示消息到达," + "topic:{},message:{}", topic, mqttMessage);
        if(topic.equals(MqttConstants.TOPIC_CHARGING_RESULT)){
            log.debug("处理开始充电结果的消息");
            handleStartChargingRes(mqttMessage);
        }else if (topic.equals(MqttConstants.TOPIC_CHARGING_PROGRESS)){
            log.debug("处理充电进度的消息");
            ChargingProgressDTO chargingProgressDTO = null;

            try {
                chargingProgressDTO = JsonUtils.fromJson(mqttMessage.toString(), ChargingProgressDTO.class);

            } catch (Exception e){
                log.error("设备返回的数据格式不对,result:{}", mqttMessage);
            }

            if (chargingProgressDTO != null){
                ChargingProgressParam chargingProgressParam = new ChargingProgressParam();
                BeanUtils.copyProperties(chargingProgressDTO,chargingProgressParam);
                JsonResult<ChargingProgressVO> chargingProgressVo = mqttContext.getCostClient().doCalcPrice(chargingProgressParam);
                log.debug("计价服务返回结果:{}",chargingProgressVo);
            }
        }

    }

    private void handleStartChargingRes(MqttMessage mqttMessage) {
        ChargingResultDTO chargingResultDTO = null;
        try {
            chargingResultDTO = JsonUtils.fromJson(mqttMessage.toString(), ChargingResultDTO.class);
        } catch (Exception e) {
            log.debug(e.toString());
            log.error("设备返回的数据格式不对,result:{}", mqttMessage);
        }
        if (!ObjectUtils.isEmpty(chargingResultDTO)) {
            String result = chargingResultDTO.getResult();
            if (Constants.RESULT_START_CHARGING_SUCCESS.equals(result)) {
                log.debug("设备有响应,并且开始充电成功！");
                log.debug("保存成功的订单记录");
                saveSuccessOrder(chargingResultDTO);
            } else {
                log.debug("设备有响应,但是设备没有开始成功！");
                log.debug("保存失败的订单记录");
                log.debug("反馈给用户，换一个充电枪！");
                log.debug("通知维修人员，及时维修！");
                saveFailOrder(mqttMessage, chargingResultDTO);
            }
        }
    }

    /**
     * 保存失败的订单
     * @param mqttMessage
     * @param chargingResultDTO
     */

    private void saveFailOrder(MqttMessage mqttMessage, ChargingResultDTO chargingResultDTO) {
        ChargingFailPO chargingFailPO = new ChargingFailPO();
        chargingFailPO.setBillId(chargingResultDTO.getOrderNo());
        chargingFailPO.setFailDesc("充电站故障-无法正常充电");
        log.debug("保存失败的订单记录,开始插入数据,{}", chargingFailPO);
        Integer row = mqttContext.getChargingFailMapper().insert(chargingFailPO);
        log.debug("保存失败的订单记录,插入数据成功，影响的行数：{}", row);
    }

    /**
     * 保存成功的订单
     * @param chargingResultDTO
     */
    private void saveSuccessOrder(ChargingResultDTO chargingResultDTO) {
        ChargingSuccessPO chargingSuccessPO = new ChargingSuccessPO();
        chargingSuccessPO.setBillId(chargingResultDTO.getOrderNo());
        chargingSuccessPO.setBillStatus(OrderStatusConstants.ORDER_STATUS_PROGRESS);
        log.debug("保存成功的订单记录，开始插入数据,{}", chargingSuccessPO);
        Integer row = mqttContext.getChargingSuccessMapper().insert(chargingSuccessPO);
        log.debug("保存成功的订单记录，插入数据成功,影响的行数：,{}", row);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.debug("MqttConsumer#deliveryComplete方法被调用了，表示消息分发完成," + "iMqttDeliveryToken:{}", iMqttDeliveryToken);
    }
}
